#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct Road
{
    int a, b; // 一条边所连接的两个顶点
    int c;    // 权值
};
// 查找根节点的函数
int getRoot(int a, vector<int> v)
{
    while (a != v[a])
        a = v[a];
    return a;
}

// 按照权值排序
bool cmp(Road a, Road b)
{
    return a.c < b.c;
}

int main()
{
    int n, m;
    cin >> n >> m;
    int a, b, i, sum = 0;
    vector<Road> G(m);

    for (i = 0; i < m; i++)
        cin >> G[i].a >> G[i].b >> G[i].c;
    vector<int> v(n + 1); // 并查集
    for (i = 1; i <= n; ++i)
        v[i] = i;
    sort(G.begin(), G.end(), cmp); // 根据权值排序
    for (i = 0; i < m; ++i)
    {
        a = getRoot(G[i].a, v);
        b = getRoot(G[i].b, v);
        if (a != b)
        {
            v[a] = b;
            sum += G[i].c;
        }
    }
    cout << sum << endl;
    return 0;
}